package com.jsh.erp.service.dailyHead;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.entities.DailyHead;
import com.jsh.erp.datasource.entities.DailyHeadExample;
import com.jsh.erp.datasource.mappers.*;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.WorkflowConfig.WorkflowConfigService;
import com.jsh.erp.service.attachment.AttachmentService;
import com.jsh.erp.service.dailyItem.DailyItemService;
import com.jsh.erp.service.log.LogService;
import com.jsh.erp.service.systemConfig.SystemConfigService;
import com.jsh.erp.service.user.UserService;
import com.jsh.erp.service.userBusiness.UserBusinessService;
import com.jsh.erp.utils.IdUtils;
import com.jsh.erp.utils.StringUtil;
import com.jsh.erp.utils.Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DailyHeadService {
    private Logger logger = LoggerFactory.getLogger(DailyHeadService.class);

    @Resource
    private DailyHeadMapper dailyHeadMapper;

    @Resource
    private DailyHeadMapperEx dailyHeadMapperEx;
    @Resource
    private LogService logService;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private WorkflowConfigService workflowConfigService;
    @Resource
    private AttachmentService attachmentService;
    @Resource
    private UserBusinessService userBusinessService;
    @Resource
    private DailyItemService dailyItemService;
    @Resource
    private UserService userService;
    @Resource
    private DailyItemMapperEx dailyItemMapperEx;
    @Resource
    private AttachmentMapperEx attachmentMapperEx;
    @Resource
    private WorkflowProcessDetailMapperEx workflowProcessDetailMapperEx;

    public DailyHead getDailyHead(String id)throws Exception {
        DailyHead result=null;
        try{
            result=dailyHeadMapper.selectByPrimaryKey(id);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    public List<DailyHead> getDailyHeadListByIds(String ids)throws Exception {
        List<String> idList = StringUtil.strToStringList(ids);
        List<DailyHead> list = new ArrayList<>();
        try{
            DailyHeadExample example = new DailyHeadExample();
            example.createCriteria().andIdIn(idList);
            list = dailyHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public List<DailyHead> getDailyHead()throws Exception {
        DailyHeadExample example = new DailyHeadExample();
        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<DailyHead> list=null;
        try{
            list=dailyHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public List<DailyHeadVo4ListEx> select(String number,String beginTime,String endTime, int offset, int rows)throws Exception {
        List<DailyHeadVo4ListEx> list=null;
        try{
            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
            list=dailyHeadMapperEx.selectByConditionDailyHead(number,beginTime,endTime, offset, rows);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public Long countDailyHead(String number,String beginTime,String endTime)throws Exception {
        Long result=null;
        try{
            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
            result=dailyHeadMapperEx.countsByDailyHead(number,beginTime,endTime);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertDailyHead(JSONObject obj, HttpServletRequest request)throws Exception {
        DailyHead dailyHead = JSONObject.parseObject(obj.toJSONString(), DailyHead.class);
        dailyHead.setUploadFlag("0");
        int result=0;
        try{
            result=dailyHeadMapper.insertSelective(dailyHead);
            logService.insertLog("每日对账",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(dailyHead.getNumber()).toString(), request);
        }catch(Exception e){
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateDailyHead(JSONObject obj, HttpServletRequest request)throws Exception {
        DailyHead dailyHead = JSONObject.parseObject(obj.toJSONString(), DailyHead.class);
        dailyHead.setUploadFlag("0");
        int result=0;
        try{
            result=dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
            logService.insertLog("每日对账",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(dailyHead.getNumber()).toString(), request);
        }catch(Exception e){
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteDailyHead(String id, HttpServletRequest request)throws Exception {
        return batchDeleteBillByIds(id.toString());
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteDailyHead(String ids, HttpServletRequest request) throws Exception{
        return batchDeleteBillByIds(ids);
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteDailyHeadByIds(String ids) throws Exception {
        String[] idArray = ids.split(",");
        int result = 0;
        try {
            result = dailyHeadMapperEx.batchDeleteDailyHeadByIds(idArray);
        } catch (Exception e) {
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteBillByIds(String ids)throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
        List<DailyHead> dhList = getDailyHeadListByIds(ids);
        for (DailyHead depotHead : dhList) {
            sb.append("[").append(depotHead.getNumber()).append("]");
            //只有未审核的单据才能被删除
            if ("0".equals(depotHead.getStatus())) {
                User userInfo = userService.getCurrentUser();
                //删除单据子表数据
                dailyItemMapperEx.batchDeleteDailyItemByDailyHeadIds(new String[]{depotHead.getId()});
                //删除单据附件
                attachmentMapperEx.batchDeleteAttachmentByHeadId(new Date(), userInfo == null ? null : userInfo.getId(), new String[]{depotHead.getId()});
                //删除待审批任务
                workflowProcessDetailMapperEx.batchDeleteByBillId(new String[]{depotHead.getNumber()});
                //删除单据主表信息
                batchDeleteDailyHeadByIds(depotHead.getId().toString());
            } else {
                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_CODE,
                        String.format("zh".equals(systemConfigService.getLanCode()) ? ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_MSG : ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_MSG_US));
            }
        }
        return 1;
    }

    public int checkIsNameExist(String id, String name) throws Exception{
        DailyHeadExample example = new DailyHeadExample();
        example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<DailyHead> list =null;
        try{
            list=dailyHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list==null?0:list.size();
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchSetStatus(String status, String dailyHeadIDs) throws Exception {
        int result = 0;
        List<String> dhIds = new ArrayList<>();
        List<String> ids = StringUtil.strToStringList(dailyHeadIDs);
        for (String id : ids) {
            DailyHead dailyHead = getDailyHead(id);
            if ("0".equals(status)) {
                if ("1".equals(dailyHead.getStatus())) {
                    dhIds.add(id);
                } else {
                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_CODE,
                            String.format("zh".equals(systemConfigService.getLanCode()) ? ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_MSG : ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_MSG_US));
                }
            } else if ("1".equals(status)) {
                if ("0".equals(dailyHead.getStatus())) {
                    dhIds.add(id);
                } else {
                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_CODE,
                            String.format("zh".equals(systemConfigService.getLanCode()) ? ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_MSG : ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_MSG_US));
                }
            }
        }
        if (dhIds.size() > 0) {
            DailyHead dailyHead = new DailyHead();
            dailyHead.setStatus(status);
            dailyHead.setUploadFlag("0");
            DailyHeadExample example = new DailyHeadExample();
            example.createCriteria().andIdIn(dhIds);
            result = dailyHeadMapper.updateByExampleSelective(dailyHead, example);
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void addDailyHeadAndDetail(String beanJson, String rows, String attachment,
                                      HttpServletRequest request, boolean passDirect,
                                      String functionId) throws Exception {
        /**处理单据主表数据*/
        DailyHead dailyHead = JSONObject.parseObject(beanJson, DailyHead.class);
        dailyHead.setId(IdUtils.getUUID());
        dailyHead.setCreateTime(new Timestamp(System.currentTimeMillis()));

        if (StringUtil.isEmpty(dailyHead.getStatus())) {
            dailyHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
        }
        try {
            dailyHead.setUploadFlag("0");
            //防止复制单据时 不把租户字段删除的**
            dailyHead.setTenantId(null);
            dailyHeadMapper.insertSelective(dailyHead);
        } catch (Exception e) {
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        //根据单据编号查询单据id
        DailyHeadExample dhExample = new DailyHeadExample();
        dhExample.createCriteria().andNumberEqualTo(dailyHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<DailyHead> list = dailyHeadMapper.selectByExample(dhExample);
        if (list != null) {
            String headId = list.get(0).getId();
            /**处理单据子表信息*/
            dailyItemService.saveDetials(rows, headId, "add", request, false);
            /**处理文件**/
            attachmentService.saveAttachment(attachment, dailyHead.getId(), request);
        }
        logService.insertLog("每日对账",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(dailyHead.getNumber()).toString(),
                StringUtil.getRequest());

        if (passDirect) {
            String keyId = userBusinessService.checkValueExist("ConfigRoleFunctions", "[" + functionId + "]", request);
            if (StringUtils.isNotEmpty(keyId)) {
                workflowConfigService.addProcessDetailWithDaily(keyId, dailyHead);
            } else {
                dailyHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                dailyHead.setUploadFlag("0");
                dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
            }
        }
    }

    /**
     * 更新单据主表及单据子表信息
     *
     * @param beanJson
     * @param rows
     * @param request
     * @throws Exception
     */
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void updateDailyHeadAndDetail(String beanJson, String rows, String attachment, HttpServletRequest request, boolean passDirect,
                                         String functionId) throws Exception {
        /**更新单据主表信息*/
        DailyHead dailyHead = JSONObject.parseObject(beanJson, DailyHead.class);

        try {
            dailyHead.setUploadFlag("0");
            //防止复制单据时 不把租户字段删除的**
            dailyHead.setTenantId(null);
            dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
        } catch (Exception e) {
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        /**单据子表信息*/
        dailyItemService.saveDetials(rows, dailyHead.getId(), "update", request, false);
        /**处理文件**/
        attachmentService.saveAttachment(attachment, dailyHead.getId(), request);
        logService.insertLog("每日对账",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(dailyHead.getNumber()).toString(),
                StringUtil.getRequest());
        if (passDirect) {
            String keyId = userBusinessService.checkValueExist("ConfigRoleFunctions", "[" + functionId + "]", request);
            if (StringUtils.isNotEmpty(keyId)) {
                workflowConfigService.addProcessDetailWithDaily(keyId, dailyHead);
            } else {
                dailyHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                dailyHead.setUploadFlag("0");
                dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
            }
        }
    }
}
